package com.jeesite.modules.web;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.entity.DonationRecord;
import com.jeesite.modules.service.DonationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Donation Controller
 * @author KBB Team
 * @version 2025-08-17
 */
@RestController
@RequestMapping("/donation")
@PropertySource("classpath:config/alipay.properties")
public class DonationController extends BaseController {

    @Autowired
    private DonationService donationService;

    // 支付宝配置
    @Value("${alipay.app-id}")
    private String appId;

    @Value("${alipay.private-key}")
    private String privateKey;

    @Value("${alipay.public-key}")
    private String alipayPublicKey;

    @Value("${alipay.gateway-url}")
    private String gatewayUrl;

    @Value("${alipay.notify-url}")
    private String notifyUrl;

    /**
     * Get donation configuration
     */
    @GetMapping("/config")
    public Map<String, Object> getConfig() {
        try {
            Map<String, Object> config = donationService.getDonationConfig();

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "捐赠配置获取成功");
            result.put("data", config);

            return result;
        } catch (Exception e) {
            logger.error("获取捐赠配置失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "获取捐赠配置失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * Pre-create donation (for payment flow)
     */
    @PostMapping("/precreate")
    public Map<String, Object> precreateDonation(@RequestBody Map<String, Object> request) {
        try {
            logger.info("收到捐赠预创建请求: {}", request);

            // 验证必要参数
            if (request.get("amount") == null || request.get("paymentMethod") == null) {
                Map<String, Object> result = new HashMap<>();
                result.put("success", false);
                result.put("message", "缺少必要参数：amount 或 paymentMethod");
                return result;
            }

            // 创建捐赠记录对象
            DonationRecord donation = new DonationRecord();

            // 设置基本信息
            donation.setAmount(new BigDecimal(request.get("amount").toString()));
            donation.setDonorName((String) request.get("donorName"));
            donation.setGameAccountId((String) request.get("gameAccountId"));
            donation.setGameNickname((String) request.get("gameNickname"));
            donation.setMessage((String) request.get("message"));
            donation.setContactInfo((String) request.get("contactInfo"));
            donation.setPaymentMethod((String) request.get("paymentMethod"));

            // 预创建捐赠记录
            DonationRecord preCreatedDonation = donationService.preCreateDonation(donation);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "捐赠预创建成功");

            Map<String, Object> data = new HashMap<>();
            data.put("id", preCreatedDonation.getId());
            data.put("paymentOrderId", preCreatedDonation.getPaymentOrderId());
            data.put("amount", preCreatedDonation.getAmount());
            data.put("paymentMethod", preCreatedDonation.getPaymentMethod());
            data.put("status", preCreatedDonation.getPaymentStatus());

            // 如果是支付宝支付，生成二维码
            if ("alipay".equals(preCreatedDonation.getPaymentMethod())) {
                try {
                    String qrCode = generateAlipayQrCode(
                        preCreatedDonation.getPaymentOrderId(),
                        preCreatedDonation.getAmount().toString(),
                        generatePaymentSubject(preCreatedDonation)
                    );
                    data.put("qrCode", qrCode);
                    data.put("qrCodeUrl", qrCode);
                    logger.info("支付宝二维码生成成功: {}", qrCode);
                } catch (Exception e) {
                    logger.error("生成支付宝二维码失败", e);
                    result.put("success", false);
                    result.put("message", "生成支付宝二维码失败: " + e.getMessage());
                    return result;
                }
            }

            result.put("data", data);
            logger.info("捐赠预创建成功，订单ID: {}", preCreatedDonation.getPaymentOrderId());
            return result;

        } catch (Exception e) {
            logger.error("预创建捐赠记录失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "预创建捐赠记录失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * Create donation
     */
    @PostMapping("/create")
    public Map<String, Object> createDonation(@RequestBody Map<String, Object> request) {
        try {
            // 创建捐赠记录对象
            DonationRecord donation = new DonationRecord();

            // 设置基本信息
            if (request.get("amount") != null) {
                donation.setAmount(new BigDecimal(request.get("amount").toString()));
            }
            donation.setDonorName((String) request.get("donorName"));
            donation.setGameAccountId((String) request.get("gameAccountId"));
            donation.setGameNickname((String) request.get("gameNickname"));
            donation.setMessage((String) request.get("message"));
            donation.setContactInfo((String) request.get("contactInfo"));
            donation.setPaymentMethod((String) request.get("paymentMethod"));

            // 创建捐赠记录
            DonationRecord savedDonation = donationService.createDonation(donation);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "捐赠记录创建成功");

            Map<String, Object> data = new HashMap<>();
            data.put("id", savedDonation.getId());
            data.put("paymentOrderId", savedDonation.getPaymentOrderId());
            data.put("amount", savedDonation.getAmount());
            data.put("paymentMethod", savedDonation.getPaymentMethod());
            data.put("status", savedDonation.getPaymentStatus());

            result.put("data", data);
            return result;

        } catch (Exception e) {
            logger.error("创建捐赠记录失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "创建捐赠记录失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * Get donation list (感谢名单)
     */
    @GetMapping("/list")
    public Map<String, Object> getDonationList(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Map<String, Object> thanksList = donationService.getThanksList(page, size);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "感谢名单获取成功");
            result.put("data", thanksList);

            return result;
        } catch (Exception e) {
            logger.error("获取感谢名单失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "获取感谢名单失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * 测试支付成功回调
     */
    @RequestMapping(value = "test-payment-success", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> testPaymentSuccess(@RequestParam String orderId) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 模拟支付成功回调
            String transactionId = "TXN" + System.currentTimeMillis();
            String callbackData = "{\"status\":\"success\",\"amount\":\"10.00\"}";

            boolean success = donationService.handlePaymentSuccess(orderId, transactionId, callbackData);

            if (success) {
                result.put("success", true);
                result.put("message", "支付成功处理完成");
                Map<String, Object> data = new HashMap<>();
                data.put("orderId", orderId);
                data.put("transactionId", transactionId);
                data.put("processed", true);
                result.put("data", data);
            } else {
                result.put("success", false);
                result.put("message", "支付成功处理失败");
            }
        } catch (Exception e) {
            logger.error("测试支付成功回调失败", e);
            result.put("success", false);
            result.put("message", "系统错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * Get donation statistics
     */
    @GetMapping("/statistics")
    public Map<String, Object> getStatistics() {
        try {
            Map<String, Object> statistics = donationService.getDonationStatistics();

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "统计信息获取成功");
            result.put("data", statistics);

            return result;
        } catch (Exception e) {
            logger.error("获取统计信息失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "获取统计信息失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * Get donation ranking
     */
    @GetMapping("/ranking")
    public Map<String, Object> getRanking(@RequestParam(defaultValue = "10") int limit) {
        try {
            List<Map<String, Object>> ranking = donationService.getDonationRanking(limit);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "排行榜获取成功");
            result.put("data", ranking);

            return result;
        } catch (Exception e) {
            logger.error("获取排行榜失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "获取排行榜失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * Get donation detail
     */
    @GetMapping("/{id}")
    public Map<String, Object> getDonationDetail(@PathVariable String id) {
        try {
            DonationRecord donation = donationService.get(id);

            Map<String, Object> result = new HashMap<>();
            if (donation != null) {
                result.put("success", true);
                result.put("message", "捐赠详情获取成功");
                result.put("data", donation);
            } else {
                result.put("success", false);
                result.put("message", "捐赠记录不存在");
            }

            return result;
        } catch (Exception e) {
            logger.error("获取捐赠详情失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "获取捐赠详情失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * 生成支付宝二维码
     */
    private String generateAlipayQrCode(String orderId, String amount, String subject) throws AlipayApiException {
        logger.info("开始生成支付宝二维码: orderId={}, amount={}, subject={}", orderId, amount, subject);

        // 创建支付宝客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
            gatewayUrl, appId, privateKey, "json", "UTF-8", alipayPublicKey, "RSA2");

        // 创建预创建请求
        AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();

        // 设置回调地址
        alipayRequest.setNotifyUrl(notifyUrl);

        // 设置业务参数
        String bizContent = String.format(
            "{\"out_trade_no\":\"%s\",\"total_amount\":\"%s\",\"subject\":\"%s\"}",
            orderId, amount, subject);
        alipayRequest.setBizContent(bizContent);

        // 执行请求
        AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);

        if (response.isSuccess()) {
            logger.info("支付宝二维码生成成功: {}", response.getQrCode());
            return response.getQrCode();
        } else {
            logger.error("支付宝二维码生成失败: code={}, msg={}, subCode={}, subMsg={}",
                response.getCode(), response.getMsg(), response.getSubCode(), response.getSubMsg());
            throw new AlipayApiException("支付宝二维码生成失败: " + response.getMsg());
        }
    }

    /**
     * 生成支付主题
     */
    private String generatePaymentSubject(DonationRecord donation) {
        String donorName = donation.getDonorName();
        if (donorName == null || donorName.trim().isEmpty()) {
            donorName = "匿名用户";
        }
        return "KBB服务器捐赠 - " + donorName;
    }

    /**
     * 提供捐赠页面
     */
    @GetMapping("/page")
    @ResponseBody
    public String donationPage() {
        try {
            // 读取静态文件内容
            java.io.InputStream is = getClass().getClassLoader().getResourceAsStream("static/donation.html");
            if (is != null) {
                try (java.util.Scanner scanner = new java.util.Scanner(is, "UTF-8").useDelimiter("\\A")) {
                    return scanner.hasNext() ? scanner.next() : "";
                }
            }
        } catch (Exception e) {
            logger.error("读取捐赠页面失败", e);
        }
        return "<!DOCTYPE html><html><head><title>页面加载失败</title></head><body><h1>页面加载失败</h1><p>请联系管理员</p></body></html>";
    }

    /**
     * 提供API测试页面
     */
    @GetMapping("/test-page")
    @ResponseBody
    public String testPage() {
        try {
            // 读取静态文件内容
            java.io.InputStream is = getClass().getClassLoader().getResourceAsStream("static/test-donation-api.html");
            if (is != null) {
                try (java.util.Scanner scanner = new java.util.Scanner(is, "UTF-8").useDelimiter("\\A")) {
                    return scanner.hasNext() ? scanner.next() : "";
                }
            }
        } catch (Exception e) {
            logger.error("读取测试页面失败", e);
        }
        return "<!DOCTYPE html><html><head><title>页面加载失败</title></head><body><h1>页面加载失败</h1><p>请联系管理员</p></body></html>";
    }

    /**
     * 测试预创建捐赠（GET请求，方便浏览器直接访问测试）
     */
    @GetMapping("/test-precreate")
    @ResponseBody
    public Map<String, Object> testPrecreate() {
        Map<String, Object> result = new HashMap<>();

        try {
            // 创建测试捐赠记录
            DonationRecord donation = new DonationRecord();
            donation.setDonorName("测试用户");
            donation.setGameAccountId("test123");
            donation.setGameNickname("测试昵称");
            donation.setAmount(new BigDecimal("10.00"));
            donation.setPaymentMethod("alipay");
            donation.setMessage("这是一个测试捐赠");
            donation.setContactInfo("test@example.com");

            // 预创建捐赠记录
            DonationRecord createdDonation = donationService.preCreateDonation(donation);

            result.put("success", true);
            result.put("message", "预创建捐赠成功");
            result.put("data", Map.of(
                "donationId", createdDonation.getId(),
                "orderId", createdDonation.getPaymentOrderId(),
                "amount", createdDonation.getAmount(),
                "status", createdDonation.getPaymentStatus()
            ));

        } catch (Exception e) {
            logger.error("测试预创建捐赠失败", e);
            result.put("success", false);
            result.put("message", "预创建失败: " + e.getMessage());
        }

        return result;
    }
}
